<!DOCTYPE html>
<html lang="en">

<head>

<!-- AdThrive Head Tag Manual -->
<script data-no-optimize="1" data-cfasync="false">
(function(w, d) {
	w.adthrive = w.adthrive || {};
	w.adthrive.cmd = w.
	adthrive.cmd || [];
	w.adthrive.plugin = 'adthrive-ads-manual';
	w.adthrive.host = 'ads.adthrive.com';var s = d.createElement('script');
	s.async = true;
	s.referrerpolicy='no-referrer-when-downgrade';
	s.src = 'https://' + w.adthrive.host + '/sites/643436a4e6d20859e40a446b/ads.min.js?referrer=' + w.encodeURIComponent(w.location.href) + '&cb=' + (Math.floor(Math.random() * 100) + 1);
	var n = d.getElementsByTagName('script')[0];
	n.parentNode.insertBefore(s, n);
})(window, document);
</script>
<!-- End of AdThrive Head Tag -->








  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-79254642-6"></script>

  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', 'UA-79254642-6');
  </script>

  <meta charset="utf-8">
  <title>Responsive map with d3.js and canvas</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="Using d3.js to create a responsive map on canvas. Example with code (d3.js v4 and v6).">
  <meta name="keywords" content="Data, Dataviz, Datavisualization, Javascript, JS, d3.js, map">
  <meta name="author" content="Yan Holtz">
  <link rel="icon" href="../img/logo/D3_single_small.png">

  <meta property="og:title" content="Responsive map with d3.js and canvas">
  <meta property="og:image" content="https://www.d3-graph-gallery.com/img/logo/D3_full_medium.png">
  <meta property="og:description" content="Using d3.js to create a responsive map on canvas. Example with code (d3.js v4 and v6).">

  <!-- Bootstrap core CSS -->
  <link href="../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

  <!-- Custom fonts for this template -->
  <link href="../vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

  <!-- Custom styles for this template -->
  <link href="../css/agency.css" rel="stylesheet">

  <!-- PRISM -->
  <script src="../LIB/prism.js"></script>
  <link href="../LIB/prism.css" rel="stylesheet" />

  <!-- JQUERY -->
  <script src="../vendor/jquery/jquery.min.js"></script>

  <!-- HTML TO CANVAS -->
  <script src="../js/html2canvas.js"></script>

  <!-- Function to parse html and js code chunks made by Yan Holtz -->
  <script src="../js/myParser.js"></script>

</head>






<body id="page-top">


<!-- THIS ALLOWS TO INSERT THE MENU THAT IS STORED IN A MENU.HTML FILE-->
<nav class="navbar navbar-expand-lg fixed-top" id="mainNav"></nav>
<script>
$(function(){
  $("#mainNav").load("../html_chunk/menu.html");
});
</script>

<!-- THIS ALLOWS TO INSERT THE MODAL OF THE MENU THAT IS STORED IN A MENU_MODAL.HTML FILE-->
<div id="modal_menu_insertion"> </div>
<script>
$(function(){
  $("#modal_menu_insertion").load("../html_chunk/menu_modal.html");
});
</script>


<!-- Header -->
<header class="masthead">
  <div class="textlanding">
      <h1>Responsive map with d3.js and canvas</h1>
      <hr class="short_hr">
      <br>
      <ul class="list-inline social-buttons">
        <li class="list-inline-item">
          <a href="https://twitter.com/R_Graph_Gallery">
            <i class="fa fa-twitter"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://github.com/holtzy">
            <i class="fa fa-github" style="color: white"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://www.linkedin.com/in/yan-holtz-2477534a/">
            <i class="fa fa-linkedin"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://www.yan-holtz.com">
            <i class="fa fa-home"></i>
          </a>
        </li>
      </ul>
      <br><br>
      <p style="max-width: 700px; margin: auto">This post extends the <a href="backgroundmap_canvas_basic.html">previous basic map</a> done with canvas. It shows how to make it responsive. Basically, resizing the window will change the map size accurately. Try it now to see how the map below behave. This example works with d3.js <code>v4</code> and <code>v6</code></p>
      <br>
      <a class="btn btn-secondary btn-md text-uppercase" href="../backgroundmap.html">Background map section</a>
      <button class="btn btn-secondary btn-md text-uppercase" onclick="myCodeDownload('chart_example_from_d3-graph-gallery.html', 'code-html-v4', 'code-js-v4')">Download code</button>
  </div>
</header>






<!-- THIS ALLOWS TO INSERT THE ADVERTISEMENT BANNER THAT IS STORED IN A BANNER.HTML FILE-->
<div id="position_for_images"> </div>
<script>
$(function(){
  $("#position_for_images").load("../html_chunk/images.html");
});
</script>











<section class="bg" style="padding-top: 20px; padding-bottom: 20px"><div class="container" >

  <center><div class="bg-light" id="result" ></div></center>

  <div class="row">

<!-- ==================== GRAPH SECTION = WHERE THE GRAPH APPEARS ==================== -->

  <div class="col-lg-5 .align-middle">
    <div style="position: -webkit-sticky; position: sticky; top: 120px">
      <br>
      <div>
        <h5>Steps:</h5>
        <ul>
          <br>
          <li>The Html part of the code just creates a <code>canvas</code>. Rest of the code adds stuff in it.</li>
          <br>
          <li>Canvas is an alternative to <code>svg</code> to draw shapes in javascript. Read an intro to canvas <a href="canvas.html">here</a>.</a></li>
          <br>
          <li>The spirit is very close to a background map built with <code>svg</code> (see <a href="backgroundmap_basic.html">here</a>). But once the projection anc the path generator are ready, shapes are drawn with <code>fill()</code> and <code>stroke()</code>.</li>
        </ul>
      </div>
    </div>
  </div>

<!-- ================================================================================= -->




<!-- ==================== CODE SECTION = WHERE THE CODE APPEARS ==================== -->
<div class="col-lg-7 text-center .align-middle">

<div class="v4-v6-toggle">
    <button id="button-show-v4" onclick="showCodeVersion('v4')" type="button" class="btn  btn-secondary btn-sm active">d3 v4</button>
    <span> | </span>
    <button id="button-show-v6" onclick="showCodeVersion('v6')" type="button" class="btn  btn-secondary btn-sm">d3 v6</button>
</div>

<!-- ========= show html code ============== -->
<aside style="position: -webkit-sticky; position: sticky; top: 120px">&larr; Edit me! </aside>
<pre class="language-html d-none d3v4-chunk"><code id="code-html-v4" contenteditable="true"><xmp><!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>

<!-- Create an element where the map will take place -->
<canvas id="my_dataviz"></canvas>

<style>
#my_dataviz{
  border: solid 1px blue;
  width: 100%;
}
</style>

</xmp></code></pre>

<pre class="language-html d-none d3v6-chunk"><code id="code-html-v6" contenteditable="true"><xmp><!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.js"></script>

<!-- Create an element where the map will take place -->
<canvas id="my_dataviz"></canvas>

<style>
#my_dataviz{
    border: solid 1px blue;
    width: 100%;
}
</style>

</xmp></code></pre>
<!-- ==================================== -->






<!-- ========= show JS code v4 ==============  -->
<pre class="language-js d-none d3v4-chunk"><code id="code-js-v4" contenteditable="true"><xmp><script>

// select the canvas and the container element
var canvas = document.getElementById('my_dataviz');

// Get the 'context'
var ctx = canvas.getContext('2d');

// A function that finishes to draw the chart for a specific device size.
function drawChart() {

  // get the current width of the div where the chart appear
  var width = parseInt( d3.select('#my_dataviz').style('width'), 10 )

  // Set the canvas height = height of the width
  var height = width/2
  ctx.height= height

console.log(width, height)
  // Set a projection for the map. Projection = transform a lat/long on a position on the 2d map.
  var projection = d3.geoMercator()
      .scale(35)
      .translate([150,100])

  // geographic path generator for given projection and canvas context
  const pathGenerator = d3.geoPath(projection, ctx);

  // Load external data and boot
  d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson", function(data){

    // remove the current map if there is one
    ctx.clearRect(0, 0, width, height)

    // initialize the path
    ctx.beginPath();

    // Got the positions of the path
    pathGenerator(data);

    // Fill the paths
    ctx.fillStyle = "#999";
    ctx.fill();

    // Add stroke
    // ctx.strokeStyle = "#69b3a2";
    // ctx.stroke()

  })

}

// Initialize the chart
drawChart()

// Add an event listener that run the function when dimension change
window.addEventListener('resize', drawChart );

</script></xmp></code></pre>
<!-- ==================================== -->

<!-- ========= show JS code v6 ==============  -->
<pre class="language-js d-none d3v6-chunk"><code id="code-js-v6" contenteditable="true"><xmp><script>

// select the canvas and the container element
const canvas = document.getElementById('my_dataviz');

// Get the 'context'
const ctx = canvas.getContext('2d');

// A function that finishes to draw the chart for a specific device size.
function drawChart() {

  // get the current width of the div where the chart appear
  const width = parseInt( d3.select('#my_dataviz').style('width'), 10 )

  // Set the canvas height = height of the width
  const height = width/2
  ctx.height= height

console.log(width, height)
  // Set a projection for the map. Projection = transform a lat/long on a position on the 2d map.
  const projection = d3.geoMercator()
      .scale(35)
      .translate([150,100])

  // geographic path generator for given projection and canvas context
  const pathGenerator = d3.geoPath(projection, ctx);

  // Load external data and boot
  d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson").then( function(data){

    // remove the current map if there is one
    ctx.clearRect(0, 0, width, height)

    // initialize the path
    ctx.beginPath();

    // Got the positions of the path
    pathGenerator(data);

    // Fill the paths
    ctx.fillStyle = "#999";
    ctx.fill();

    // Add stroke
    // ctx.strokeStyle = "#69b3a2";
    // ctx.stroke()

  })

}

// Initialize the chart
drawChart()

// Add an event listener that run the function when dimension change
window.addEventListener('resize', drawChart );
</script></xmp></code></pre>
<!-- ==================================== -->








</div>


  </div>
</div>
</section>
<br>


<!-- ============================ -->








<!-- ============================ RELATED BLOCKS ============================ -->

<section class="bg-light" style="padding-top: 70px; padding-bottom: 70px">
  <div class="container">
    <div class="row">
      <div class="col-lg-5 text-center align-self-center">
        <h3 class="text-uppercase">Related blocks  &rarr;</h3>
      </div>
      <div class="col-lg-5">
        <ul>
          <li><i>Mapping with Canvas - </i><a href="https://bl.ocks.org/pnavarrc/43dd75fb3693588c99ff">link</a></li>
          <br>
          <li><i>Projection Transitions - </i><a href="https://bl.ocks.org/alexmacy/6700d44240d2b6d3ec9767a5a5854e42">link</a></li>
        </ul>
      </div>
    </div>
  </div>
</section>

















<!-- ============================ CONTACT SECTION ============================ -->

  <!-- ANCHOR -->
  <a name="contactanchor"></a>


<section id="contact" class="bg" style="background-color: white"></section>

<!-- THIS ALLOWS TO INSERT THE CONTACT CHUNK THAT IS STORED IN A CONTACT.HTML FILE-->
<script>
$(function(){
  $("#contact").load("../html_chunk/contact.html");
});
</script>













<!-- ============================ FOOTER SECTION ============================ --><footer class="bg-light" id="myFooter"></footer>

<!-- THIS ALLOWS TO INSERT THE FOOTER THAT IS STORED IN A FOOTER.HTML FILE-->
<script>
$(function(){
  $("#myFooter").load("../html_chunk/footer.html");
});
</script>

<!-- ============================ -->




















<!-- ============================ JAVASCRIPT SECTION ============================ -->

<!-- Bootstrap core JavaScript -->
<script src="../vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

<!-- Custom scripts for this template -->
<script src="../js/agency.min.js"></script>

<!-- Activate the bootstrap tooltip, must be after jQuery load -->
<script>
  $(function () {
      $('[data-toggle="tooltip"]').tooltip()
  })
</script>



<script>
showCodeVersion('v4')
</script>







</body>

</html>
